package com.jiawa.train.business.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jiawa.train.business.domain.po.DailyTrainCarriage;
import com.jiawa.train.business.domain.po.TrainCarriage;
import com.jiawa.train.business.enums.SeatColEnum;
import com.jiawa.train.business.mapper.DailyTrainCarriageMapper;
import com.jiawa.train.business.req.DailyTrainCarriageQueryReq;
import com.jiawa.train.business.req.DailyTrainCarriageSaveReq;
import com.jiawa.train.business.resp.DailyTrainCarriageQueryResp;
import com.jiawa.train.business.service.IDailyTrainCarriageService;
import com.jiawa.train.business.service.ITrainCarriageService;
import com.jiawa.train.common.exception.BusinessException;
import com.jiawa.train.common.exception.BusinessExceptionEnum;
import com.jiawa.train.common.resp.PageResp;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 每日车厢 服务实现类
 * </p>
 *
 * @author hrz
 * @since 2025-09-07
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class DailyTrainCarriageServiceImpl extends ServiceImpl<DailyTrainCarriageMapper, DailyTrainCarriage> implements IDailyTrainCarriageService {

    private final ITrainCarriageService trainCarriageService;
    
    @Override
    public PageResp<DailyTrainCarriageQueryResp> queryList(DailyTrainCarriageQueryReq req) {
        Page<DailyTrainCarriage> page = this.lambdaQuery()
                .eq(req.getDate()!=null,DailyTrainCarriage::getDate, req.getDate())
                .eq(req.getTrainCode()!=null,DailyTrainCarriage::getTrainCode, req.getTrainCode())
                .orderByDesc(req.getDate()!=null,DailyTrainCarriage::getDate)
                .orderByAsc(req.getTrainCode()!=null,DailyTrainCarriage::getTrainCode)
                .page(new Page<>(req.getPage(), req.getSize()));
        List<DailyTrainCarriage> records = page.getRecords();
        if(ObjectUtil.isEmpty(records)){
            PageResp<DailyTrainCarriageQueryResp> r = new PageResp<>();
            r.setList(new ArrayList<>());
            r.setTotal(0L);
            return r;
        }
        List<DailyTrainCarriageQueryResp> respList = BeanUtil.copyToList(records, DailyTrainCarriageQueryResp.class);
        PageResp<DailyTrainCarriageQueryResp> r = new PageResp<>();
        r.setList(respList);
        r.setTotal(page.getTotal());
        return r;
    }

    @Override
    public void delete(Long id) {
        if(ObjectUtil.isEmpty(id)){
            throw new BusinessException(BusinessExceptionEnum.ID_NULL);
        }
        this.removeById(id);
    }

    @Override
    public void saveDailyTrainCarriage(DailyTrainCarriageSaveReq req) {
        //2.判断是否是更新
        //计算列数和总座位数
        List<SeatColEnum> colsByType = SeatColEnum.getColsByType(req.getSeatType());
        req.setColCount(colsByType.size());
        req.setSeatCount(colsByType.size() * req.getRowCount());
        DailyTrainCarriage dailyTrainCarriage = BeanUtil
                .copyProperties(req, DailyTrainCarriage.class);
        if(ObjectUtil.isNotEmpty(req.getId())){
            //更新
            dailyTrainCarriage.setUpdateTime(LocalDateTime.now());
            this.updateById(dailyTrainCarriage);
        }else{
            //新增
            //1.唯一性确认
            DailyTrainCarriage one = this.lambdaQuery()
                    .eq(DailyTrainCarriage::getDate, req.getDate())
                    .eq(DailyTrainCarriage::getTrainCode, req.getTrainCode())
                    .eq(DailyTrainCarriage::getIndex, req.getIndex())
                    .one();
            if (ObjectUtil.isNotEmpty(one)|| one != null ) {
                throw new BusinessException(BusinessExceptionEnum.BUSINESS_DAILY_TRAIN_CARRIAGE_UNIQUE_ERROR);
            }
            dailyTrainCarriage.setCreateTime(LocalDateTime.now());
            dailyTrainCarriage.setUpdateTime(LocalDateTime.now());
            this.save(dailyTrainCarriage);
        }

    }

    @Override
    public void genDaily(Date date, String code) {
        //1.先清空该日该车次的车厢信息
        this.lambdaUpdate()
                .eq(DailyTrainCarriage::getDate, date)
                .eq(DailyTrainCarriage::getTrainCode, code)
                .remove();
        //2.查询出该车次的基础车厢信息
        List<TrainCarriage> list = trainCarriageService.lambdaQuery()
                .eq(TrainCarriage::getTrainCode, code)
                .orderByAsc(TrainCarriage::getIndex)
                .list();
        if(ObjectUtil.isEmpty(list)){
            log.info("该车次没有车厢信息");
            return;
        }
        //3.生成每日车厢信息
        for (TrainCarriage carriage : list) {
            DailyTrainCarriage dailyTrainCarriage = BeanUtil.copyProperties(carriage, DailyTrainCarriage.class);
            dailyTrainCarriage.setId(null);
            dailyTrainCarriage.setDate(date);
            dailyTrainCarriage.setCreateTime(LocalDateTime.now());
            dailyTrainCarriage.setUpdateTime(LocalDateTime.now());
            this.save(dailyTrainCarriage);
        }
    }

    @Override
    public List<DailyTrainCarriage> selectByTrainCodeAndSeatType(String trainCode, String seatType) {
        return this.lambdaQuery()
                .eq(DailyTrainCarriage::getTrainCode, trainCode)
                .eq(DailyTrainCarriage::getSeatType, seatType)
                .orderByAsc(DailyTrainCarriage::getIndex)
                .list();
    }
}
